<html>
	<title>Macros in RARS</title>
	<body>
		<h3> Introduction to macros</h3>
		<p>Patterson and Hennessy define a <b>macro</b> as <i>a pattern-matching and replacement facility 
		that provides a simple mechanism to name a frequently used sequence of instructions</i> [1].
		This permits the programmer to specify the instruction sequence by invoking the macro.  This requires
		only one line of code for each use instead of repeatedly typing
		in the instruction sequence each time.  It follows the axiom "define once, use many times," which
		not only reduces the chance for error but also facilitates program maintenance.</p>

		<p>Macros are like procedures (subroutines) in this sense but operate differently than procedures.  
		Procedures in assembly language follow particular protocols for procedure definition, call and return.
		Macros operate by substituting the macro body for each use at the time of assembly.  This substitution
		is called <i>macro expansion.</i>.  They do not require the protocols and execution overhead of procedures.</p>
		
		<p>As a simple example, you may want to terminate your program from a number of locations.  If you are running
		from the RARS IDE, you will use system call 10, <tt>exit</tt>.  The instruction sequence is pretty easy</p>
		<pre>
		li a7, 10
		ecall		</pre>
		but still tedious.  You can define a macro, let's call it <tt>done</tt>, to represent this sequence
		<pre>
		.macro done
		li a7, 10
		ecall
		.end_macro		</pre>
		then invoke it whenever you wish with the statement
		<pre>
		done</pre>  
		At assembly time, the assembler will replace each occurrence of the statement <tt>done</tt> with the two-statement
		sequence
		<pre>
		li a7, 10
		ecall		</pre>
		This is the macro expansion.  The runtime simulator is unaware of macros or macro expansion.</p>
		
		<p>If running RARS from the command line, perhaps you want to return a termination value.  This can be done
		with syscall 93, <tt>exit2</tt>, which takes the termination value as an argument.  An equivalent macro,
		let's call it <tt>terminate</tt>  would be
		<pre>
		.macro terminate (%termination_value)
		li a0, %termination_value
		li a7, 93
		ecall
		.end_macro		</pre>
		This macro defines a <i>formal parameter</i> to represent the termination value.  You would invoke it 
		with the statement
		<pre>
		terminate (1)</pre>
		to terminate with value 1.  Upon assembly,
		the statement <tt>terminate (1)</tt> would be replaced by the three-statement sequence
		<pre>
		li a0, 1
		li a7, 17
		ecall		</pre>
		The <i>argument value</i>, 1, is substituted wherever the formal parameter <tt>%termination_value</tt> appears
		in the macro body.
		This is a textual substitution.  Note that in this example the argument value must be an integer, not a 
		register name or a label, because the parameter is used as the second operand in the Load Immediate operation.</p>
		
		<p>In RARS, a macro is similar to an extended (pseudo) instruction. They are distinguished in that the expansion of
		extended instructions is supported by an internally-defined specification language and mechanism which can manipulate argument values.
		The macro facility can only substitute argument values as given, and it uses a separate mechanism from extended instructions. </p>
		
		<p>Additional examples and details follow.</p>

		<h3> How to define macros </h3>
		The first line begins with a <tt>.macro</tt> directive followed by an optional list of formal parameters. 
		Placing commas between parameters and parentheses around the list is optional.
		<p>
			Each formal parameter is an identifier that begins with a <tt>%</tt> character.  For compatibility with
			the SPIM preprocessor APP, it may alternatively begin with <tt>$</tt>.
		</p>
		<p>
		The lines that follow define the body of the macro.  Use the formal parameters as appropriate.  The body
		may contain data segments as well as text segments.
		</p>
		<p>The macro definition finishes with a <tt>.end_macro</tt> directive.
		</p>
		<p>See the Notes below for additional information.</p>
		
		<h3> How to use macros</h3>
		
		To invoke a macro, form a statement consisting of the macro name and then one token for each argument 
		to be substituted for its corresponding formal parameter by the assembler. 
		The argument list may optionally be surrounded by parentheses.
		Arguments may be separated either by spaces or commas. 
		<p>
		Macro expansion is a pre-processing task for assemblers.
		</p>
		<h3> Notes</h3>
		<ul>
			<li>
				A macro definition must appear before its use.  No forward references.
			</li>
			<li>
				All macro definitions are local in each file and they cannot be global.
			</li>
			<li>
				Nested macro definitions are not supported. No <tt>.macro</tt> directive should appear inside body of a macro definition. 
			</li>
			<li>
				A macro definition can contain a call to a previously-defined macro.  Only backward references are allowed.
			</li>
			<li>
				Labels placed in the body of a macro definition will not have same name after macro expansion. 
				During expansion, their name will be followed by "_M#" where # will be a unique number for each macro expansion.
			</li>
			<li>
				Two macros with the same name but different number of parameters are considered different and both can be used.
			</li>
			<li>
				A macro defined with the same name and same number of parameters as another macro defined before it will be ignored.
			</li>
			<li>
				Each argument in a macro call can only be a single language element (token).  For instance "4($t0)" cannot be an argument.
			</li>
			<li>
				Macros are a part of the assembler, not the ISA. So the syntax might be different with other assemblers. 
				For compatibility with the SPIM simulator, <i>SPIM-style macros are also supported in RARS</i>. SPIM-style macros are same as RARS but formal parameters begin with "$" instead of "%".
			</li>
		</ul>
		<h3> Examples</h3>
		<ul>
			<li>
				Printing an integer (argument may be either an immediate value or register name): 				
				<pre><tt>	.macro print_int (%x)
	li a7, 1
	add $a0, $zero, %x
	syscall
	.end_macro
	
	print_int ($s0)
	print_int (10)
</tt></pre>
			</li>
			<li>
				Printing a string (macro will first assign a label to its parameter in data segment then print it): 				
				<pre><tt>	.macro print_str (%str)
	.data
myLabel: .asciiz %str
	.text
	li a7, 4
	la $a0, myLabel
	syscall
	.end_macro
	
	print_str ("test1")	#"test1" will be labeled with name "myLabel_M0"
	print_str ("test2")	#"test2" will be labeled with name "myLabel_M1"
</tt></pre>
			</li>
			<li>
				Implementing a simple for-loop: 				
	<pre><tt>	# generic looping mechanism
	.macro for (%regIterator, %from, %to, %bodyMacroName)
	add %regIterator, $zero, %from
	Loop:
	%bodyMacroName ()
	add %regIterator, %regIterator, 1
	ble %regIterator, %to, Loop
	.end_macro
	
	#print an integer
	.macro body()
	print_int $t0
	print_str "\n"
	.end_macro
	
	#printing 1 to 10:
	for ($t0, 1, 10, body)
</tt></pre>
				The <tt>for</tt> macro has 4 parameters. <tt>%regIterator</tt> should be the name of a register which iterates from <tt>%from</tt> to <tt>%to</tt> and in each iteration <tt>%bodyMacroName</tt> will be expanded and run.
				Arguments for 
				<tt>%from</tt> and <tt>%to</tt> can be either a register name or an immediate value, and <tt>%bodyMacroName</tt> should be name of a macro that has no parameters.
			</li>
		</ul>
<h3>Macro source line numbers</h3>
<p>For purpose of error messaging and Text Segment display, RARS attempts to display line numbers for both the definition and use of the pertinent
macro statement.  If an error message shows the line number in the form "<tt>X->Y</tt>" (e.g. "<tt>20->4</tt>"), then <tt>X</tt> is the line number in the expansion
(use) where the error was detected and <tt>Y</tt> is the line number in the macro definition.  In the Text Segment display
of source code, the macro definition 
line number will be displayed within brackets, e.g. "<tt>&lt;4&gt;</tt>", at the point of expansion.  Line numbers should correspond to the
numbers you would see in the text editor. </p>

<h3>The .eqv directive</h3>
<p>The <tt>.eqv</tt> directive (short for "equivalence") is similar to <tt>#define</tt> in C or C++.  It 
is used to substitute an arbitrary string for an identifier.  It is useful but much less powerful than macros.  
It was developed independently of the macro facility.
</p>
<p>Using <tt>.eqv</tt>, you can specify simple substitutions that provide "define once, use many times" capability at assembly 
pre-processing time.  For example, once you define
<pre>
       .eqv  LIMIT      20
       .eqv  CTR        t2
       .eqv  CLEAR_CTR  add  CTR, zero, 0</pre>
then you can refer to them in subsequent code:
<pre>
       li a7,1
       CLEAR_CTR
loop:  move a0, CTR
       syscall
       add   CTR, CTR, 1
       blt   CTR, LIMIT, loop
       CLEAR_CTR</pre>
During assembly pre-processing, the <tt>.eqv</tt> substitutions will be applied.  The resulting code is
<pre>
       li   a7,1
       add  t2, zero, 0
loop:  move a0, t2
       syscall
       add  t2, t2, 1
       blt  t2, 20, loop
       add  t2, zero, 0</pre>
which when run will display the values 0 through 19 on one line with no intervening spaces.
</p>
<p>Note that the substitution string is not limited to a single token.  Like <tt>.macro</tt>, <tt>.eqv</tt> is local to the file
in which it is defined, and must be defined prior to use.  Macro bodies can contain references to <tt>.eqv</tt> directives.
 </p>

 <h3>The .include directive</h3>
 <p>The <tt>.include</tt> directive has one operand, a quoted filename.  When the
 directive is carried out, the contents of the specified file are substituted for the directive.  This occurs
 during assembly preprocessing.  It is like <tt>#include</tt> in C or C++.</p>
 
 <p><tt>.include</tt> is designed to make  macro and equivalence (.eqv directive) use
 more convenient.  Both macro definitions and equivalence definitions are <i>local</i>, which means they can be used only
 in the same file where defined.  Without <tt>.include</tt>, you would have to repeat their definitions in every
 file where you want to use them.  Besides being tedious, this is poor programming practice; remember
 "define once, use many times."  Now you can define macros and equivalences in a separate file, then include it 
 in any file where you want to use them.</p>
 
 <p>The <tt>.include</tt> preprocessor will detect and flag any circular includes (file that includes itself, directly or
 indirectly).</pp>
 
 <p>The use of <tt>.include</tt> presents some challenges for error messaging and for source code numbering in the Text
 Segment display.  If a file being included has any assembly errors, the filename and line number in the error 
 message should refer to the file being included, not the file it was substituted into.  Similarly, the line number
 given in the Text Segment source code display refers to the line in the file being included.  Thus the displayed line numbers do not
 monotonically increase - this is also the case when using the "assemble all" setting.  Line numbers should correspond to the numbers
 you would see in the text editor.</p>
 
 <p>As a simple example, you could define the <tt>done</tt> macro (and others) in a separate file
 then include it wherever you need it.  Suppose "macros.asm" contains the following:
 		<pre>
		.macro done
		li a7,10
		syscall
		.end_macro		</pre>
 
 You could then include it in a different source file something like this:
  		<pre>
		.include "macros.asm"
		.data
value:		.word	 13
		.text
		li	 a7, 1
		lw	 a0, value
		syscall
		done		</pre>
<p>During assembly preprocessing, this would be expanded to
  		<pre>
		.macro done
		li a7,10
		syscall
		.end_macro	
		.data
value:		.word	 13
		.text
		li	 a7, 1
		lw	 a0, value
		syscall
		done		</pre>
<p>The assembler will then perform the appropriate macro expansion.


 
<h3>Acknowledgements</h3>
<p>All of the RARS macro functionality comes straight from MARS.The MARS macro facility was developed in 2012 by
	Mohammad Hossein Sekhavat, sekhavat17@gmail.com, while an engineering student at Sharif University in Tehran.  MARS
	creators Pete and Ken are incredibly grateful for his contribution!  Pete developed <tt>.eqv</tt> and <tt>.include</tt>
	at about the same time.</p>

<h3>References</h3>
		<p>[1] <i>Computer Organization and Design: The Hardware/Software Interface, Fourth Edition,</i> Patterson and Hennessy, 
		Morgan Kauffman Publishers, 2009.</p>
	</body>
</html>